const MapKeys = require('../template')

console.log("=== MapKeys 基础测试 ===")

// 测试基本键映射
console.log(
  "基本键映射:", (() => {
    const obj = { a: 1, b: 2, c: 3 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => key.toUpperCase())

    return typeof mapped === 'object' &&
      mapped.A === 1 &&
      mapped.B === 2 &&
      mapped.C === 3 &&
      !('a' in mapped) &&
      !('b' in mapped) &&
      !('c' in mapped)
  })()
)

// 测试键前缀映射
console.log(
  "键前缀映射:", (() => {
    const obj = { name: 'John', age: 30 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `user_${key}`)

    return typeof mapped === 'object' &&
      mapped.user_name === 'John' &&
      mapped.user_age === 30 &&
      !('name' in mapped) &&
      !('age' in mapped)
  })()
)

// 测试键后缀映射
console.log(
  "键后缀映射:", (() => {
    const obj = { first: 'John', last: 'Doe' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `${key}_name`)

    return typeof mapped === 'object' &&
      mapped.first_name === 'John' &&
      mapped.last_name === 'Doe' &&
      !('first' in mapped) &&
      !('last' in mapped)
  })()
)

// 测试键转换映射
console.log(
  "键转换映射:", (() => {
    const obj = { firstName: 'John', lastName: 'Doe' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => key.replace(/([A-Z])/g, '_$1').toLowerCase())

    return typeof mapped === 'object' &&
      mapped.first_name === 'John' &&
      mapped.last_name === 'Doe' &&
      !('firstName' in mapped) &&
      !('lastName' in mapped)
  })()
)

// 测试空对象键映射
console.log(
  "空对象键映射:", (() => {
    const obj = {}
    const mapped = MapKeys.mapKeys(obj, (value, key) => key.toUpperCase())

    return typeof mapped === 'object' &&
      Object.keys(mapped).length === 0
  })()
)

// 测试单属性键映射
console.log(
  "单属性键映射:", (() => {
    const obj = { test: 'value' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `new_${key}`)

    return typeof mapped === 'object' &&
      mapped.new_test === 'value' &&
      !('test' in mapped)
  })()
)

// 测试数字键映射
console.log(
  "数字键映射:", (() => {
    const obj = { 0: 'zero', 1: 'one', 2: 'two' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `num_${key}`)

    return typeof mapped === 'object' &&
      mapped.num_0 === 'zero' &&
      mapped.num_1 === 'one' &&
      mapped.num_2 === 'two' &&
      !('0' in mapped) &&
      !('1' in mapped) &&
      !('2' in mapped)
  })()
)

// 测试特殊字符键映射
console.log(
  "特殊字符键映射:", (() => {
    const obj = { 'key-with-dash': 'value1', 'key.with.dot': 'value2' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => key.replace(/[-.]/g, '_'))

    return typeof mapped === 'object' &&
      mapped.key_with_dash === 'value1' &&
      mapped.key_with_dot === 'value2' &&
      !('key-with-dash' in mapped) &&
      !('key.with.dot' in mapped)
  })()
)

// 测试布尔值键映射
console.log(
  "布尔值键映射:", (() => {
    const obj = { true: 'yes', false: 'no' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `is_${key}`)

    return typeof mapped === 'object' &&
      mapped.is_true === 'yes' &&
      mapped.is_false === 'no' &&
      !('true' in mapped) &&
      !('false' in mapped)
  })()
)

// 测试空字符串键映射
console.log(
  "空字符串键映射:", (() => {
    const obj = { '': 'empty key', 'a': 'normal key' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => key === '' ? 'empty' : `key_${key}`)

    return typeof mapped === 'object' &&
      mapped.empty === 'empty key' &&
      mapped.key_a === 'normal key' &&
      !('' in mapped) &&
      !('a' in mapped)
  })()
)

// 测试函数值键映射
console.log(
  "函数值键映射:", (() => {
    const func = () => 'hello'
    const obj = { method: func, data: 'value' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `func_${key}`)

    return typeof mapped === 'object' &&
      mapped.func_method === func &&
      mapped.func_data === 'value' &&
      !('method' in mapped) &&
      !('data' in mapped)
  })()
)

// 测试对象值键映射
console.log(
  "对象值键映射:", (() => {
    const nested = { value: 'nested' }
    const obj = { nested: nested, simple: 'value' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `obj_${key}`)

    return typeof mapped === 'object' &&
      mapped.obj_nested === nested &&
      mapped.obj_simple === 'value' &&
      !('nested' in mapped) &&
      !('simple' in mapped)
  })()
)

// 测试数组值键映射
console.log(
  "数组值键映射:", (() => {
    const arr = [1, 2, 3]
    const obj = { items: arr, count: 3 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `arr_${key}`)

    return typeof mapped === 'object' &&
      mapped.arr_items === arr &&
      mapped.arr_count === 3 &&
      !('items' in mapped) &&
      !('count' in mapped)
  })()
)

// 测试null值键映射
console.log(
  "null值键映射:", (() => {
    const obj = { nullValue: null, normalValue: 'test' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `null_${key}`)

    return typeof mapped === 'object' &&
      mapped.null_nullValue === null &&
      mapped.null_normalValue === 'test' &&
      !('nullValue' in mapped) &&
      !('normalValue' in mapped)
  })()
)

// 测试undefined值键映射
console.log(
  "undefined值键映射:", (() => {
    const obj = { undefinedValue: undefined, normalValue: 'test' }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `undef_${key}`)

    return typeof mapped === 'object' &&
      mapped.undef_undefinedValue === undefined &&
      mapped.undef_normalValue === 'test' &&
      !('undefinedValue' in mapped) &&
      !('normalValue' in mapped)
  })()
)

// 测试复杂对象键映射
console.log(
  "复杂对象键映射:", (() => {
    const obj = {
      user: { name: 'John', age: 30 },
      posts: [{ title: 'Post 1' }, { title: 'Post 2' }],
      meta: { count: 2 },
      settings: { theme: 'dark' }
    }
    const mapped = MapKeys.mapKeys(obj, (value, key) => `api_${key}`)

    return typeof mapped === 'object' &&
      mapped.api_user === obj.user &&
      mapped.api_posts === obj.posts &&
      mapped.api_meta === obj.meta &&
      mapped.api_settings === obj.settings &&
      !('user' in mapped) &&
      !('posts' in mapped) &&
      !('meta' in mapped) &&
      !('settings' in mapped)
  })()
)

// 测试键映射保持值不变
console.log(
  "键映射保持值不变:", (() => {
    const obj = { a: 1, b: 2, c: 3 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => key.toUpperCase())

    return mapped.A === 1 &&
      mapped.B === 2 &&
      mapped.C === 3 &&
      mapped.A === obj.a &&
      mapped.B === obj.b &&
      mapped.C === obj.c
  })()
)

// 测试键映射函数参数
console.log(
  "键映射函数参数:", (() => {
    const obj = { a: 1, b: 2 }
    let callCount = 0
    const mapped = MapKeys.mapKeys(obj, (value, key) => {
      callCount++
      return `${key}_${value}`
    })

    return callCount === 2 &&
      mapped.a_1 === 1 &&
      mapped.b_2 === 2
  })()
)

// 测试键映射返回相同键
console.log(
  "键映射返回相同键:", (() => {
    const obj = { a: 1, b: 2 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => key)

    return mapped.a === 1 &&
      mapped.b === 2 &&
      mapped === obj // 应该是同一个对象
  })()
)

// 测试键映射返回重复键
console.log(
  "键映射返回重复键:", (() => {
    const obj = { a: 1, b: 2, c: 3 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => 'same')

    return typeof mapped === 'object' &&
      mapped.same === 3 && // 最后一个值会覆盖前面的
      Object.keys(mapped).length === 1
  })()
)

// 测试键映射返回undefined键
console.log(
  "键映射返回undefined键:", (() => {
    const obj = { a: 1, b: 2 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => undefined)

    return typeof mapped === 'object' &&
      Object.keys(mapped).length === 0
  })()
)

// 测试键映射返回null键
console.log(
  "键映射返回null键:", (() => {
    const obj = { a: 1, b: 2 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => null)

    return typeof mapped === 'object' &&
      mapped.null === 2 && // null会被转换为字符串'null'
      Object.keys(mapped).length === 1
  })()
)

// 测试键映射返回数字键
console.log(
  "键映射返回数字键:", (() => {
    const obj = { a: 1, b: 2 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => value)

    return typeof mapped === 'object' &&
      mapped[1] === 1 &&
      mapped[2] === 2 &&
      !('a' in mapped) &&
      !('b' in mapped)
  })()
)

// 测试键映射返回Symbol键
console.log(
  "键映射返回Symbol键:", (() => {
    const sym = Symbol('test')
    const obj = { a: 1, b: 2 }
    const mapped = MapKeys.mapKeys(obj, (value, key) => sym)

    return typeof mapped === 'object' &&
      mapped[sym] === 2 && // 最后一个值会覆盖前面的
      Object.keys(mapped).length === 0 // Symbol键不会出现在Object.keys中
  })()
)

console.log("=== MapKeys 基础测试完成 ===")
